package com.woniuxy.zuul.filter;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import com.netflix.zuul.exception.ZuulException;
import com.woniuxy.commons.dto.AuthDto;
import com.woniuxy.commons.entity.ResponseEntity;
import com.woniuxy.commons.service.RemoteAuthService;
import com.woniuxy.commons.utils.JwtUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * @author： 雷鹏
 * Date: 2020/7/21 20:39
 */
@Component
public class CustomZuulFilter extends ZuulFilter {

    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

    @Autowired
    private RemoteAuthService remoteAuthService;

    // 是否进行拦截，返回true表示拦截
    // 用法：根据请求的url决定是否拦截
    @Override
    public boolean shouldFilter() {
        // 获取上下文对象
        RequestContext context = RequestContext.getCurrentContext();
        // 获取request
        HttpServletRequest request = context.getRequest();
        // 获取uri
        String uri = request.getRequestURI();
        System.out.println(uri);

        if (uri.endsWith(".html") || uri.endsWith(".js") || uri.endsWith(".css") || uri.endsWith(".jpg") || uri.endsWith(".mp4")) {
            return false;
        }

        // 判断
        if (uri.startsWith("/principal")) {
            return true;
        }

        if (uri.startsWith("/classteacher")) {
            System.out.println("拦截");
            return true;
        }
        return false;
    }

    @Override
    public Object run() throws ZuulException {

        // 获取上下文对象
        RequestContext context = RequestContext.getCurrentContext();
        // 获取request
        HttpServletRequest request = context.getRequest();
        // 获取refreshToken
        String refreshToken = request.getHeader("refreshToken");

        // 获取response
        HttpServletResponse response = context.getResponse();
        System.out.println("refreshToken为：" + refreshToken);
        // 判断
        if (refreshToken == null || refreshToken.length() == 0 || refreshToken.equals("[object Object]")) {
            goLogin(context, response);
            return null;
        }
        // 判断是否伪造、过期 用refreshToken作为key去redis中获取数据
        if (redisTemplate.opsForHash().entries("refreshToken") == null) {
            // 去登陆
            goLogin(context, response);
            return null;
        }

        // 获取token，对token进行校验
        String token = request.getHeader("token");
        if (JwtUtil.validate(token) == JwtUtil.STATUS_ERROR) {
            // token非法、去登陆
            goLogin(context, response);
            return null;
        }

        //token过期
        if (JwtUtil.validate(token) == JwtUtil.STATUS_EXPIRE) {

            // 刷新token
            AuthDto authDto = remoteAuthService.refresh(refreshToken);
            // 返回数据,在请求完成之后才会返回数据
            response.setHeader("token", authDto.getToken());
        }

        return null;
    }

    private void goLogin(RequestContext context, HttpServletResponse response) {
        // 请求结束
        context.setSendZuulResponse(false);
        //
        response.setContentType("application/json;charset=utf-8");
        ResponseEntity responseDto = new ResponseEntity();
        responseDto.setCode(302);
        responseDto.setMsg("请登录");

        try {
            String data = new ObjectMapper().writeValueAsString(responseDto);
            response.getWriter().write(data);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    // 指定过滤器的类型 pre post route error
    @Override
    public String filterType() {
        return "pre";
    }

    // 指定过滤器执行的顺序，可以是负数，数字越小越先执行（同一种过滤器类型）
    @Override
    public int filterOrder() {
        return -10000;
    }

}
